package cn.edu.cug.cs.gtl.docsrv.raw.manager;

import cn.edu.cug.cs.gtl.common.Pair;
import cn.edu.cug.cs.gtl.docsrv.config.Configuration;
import cn.edu.cug.cs.gtl.mybatis.Session;
import cn.edu.cug.cs.gtl.mybatis.mapper.raw.*;
import cn.edu.cug.cs.gtl.mybatis.metadata.RawUtils;
import cn.edu.cug.cs.gtl.protos.TimeValue;

import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 基于Oracle实现的原始数据管理器
 * RAW_ITEM表中存放原始数据的条目信息
 * 本地文件系统存放原始文件
 */
public class LocalRawManager extends RawManager {
    /**
     * 构造函数
     *
     * @param session
     */
    public LocalRawManager(Session session) {
        super(session);
        File f = new File(Configuration.getManagerConfig().getLocalRawDataRoot());
        if(!f.exists()){
            f.mkdirs();
        }
        File fTmp = new File(Configuration.getManagerConfig().getLocalDataRoot()+File.separator+"tmp");
        if(!fTmp.exists()){
            fTmp.mkdirs();
        }
    }

    /**
     * 将一个由rawItem+rawFile组成的原始文档插入数据库
     *
     * @param rawItem 原始元数据信息,
     *                其中的rawUrl一定要设置值，形式如下
     *                file:/data/tmp/rawExample.zip
     * @param rawFile 原始文件内容
     * @return
     */
    @Override
    public boolean insert(RawItem rawItem, RawFile rawFile) {
        try {
//            writeToFileSystem(rawItem,rawFile);
//            写入元数据
            RawItemMapper rawItemMapper = session.getMapper(RawItemMapper.class);
//            rawItem.setRawInternalId(rawItemMapper.maxInternalId().add(BigDecimal.ONE));
            rawItemMapper.insert(rawItem);
            RawFileMapper rawFileMapper = session.getMapper(RawFileMapper.class);
//            rawFile.setRawInternalId(rawFileMapper.maxInternalId().add(BigDecimal.ONE));
            rawFileMapper.insert(rawFile);
            session.commit();
            return true;
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 将RawAll分解成RawItem和RawFile，
     * 然后将RawItem插入数据表RAW_ITEM，
     * 将RawFile插入数据表RAW_FILE，;
     * @param rawAll
     * @return
     */
    @Override
    public boolean insert(RawAll rawAll) {
        Pair<RawItem,RawFile> p = RawUtils.fromRawAll(rawAll);
        RawAllMapper rawAllMapper = session.getMapper(RawAllMapper.class);
        rawAllMapper.insert(rawAll);
        session.commit();

        return insert(p.getFirst(),p.getSecond());
    }

    @Override
    public void insert(RawCatalog rawCatalog) {
        RawCatalogMapper rawCatalogMapper = session.getMapper(RawCatalogMapper.class);
        rawCatalogMapper.insert(rawCatalog);
        session.commit();
    }

    /**
     * 读取本地目录中的所有原始文档，将其插入原始库中
     *
     * @param localDir 本地目录
     * @return 成功返回true, 否则返回false
     */
    @Override
    public boolean insert(String localDir) {
//        try {
//
//            File file = new File(localDir);
//            if (!file.isDirectory())
//                return false;
//            File parent = file.getParentFile();
//
//            List<RawCatalog> catalogs = localDirToCatalogs(localDir);
//            for(RawCatalog rawCatalog: catalogs){
//                file = new File(parent.getAbsolutePath()+File.separator+rawCatalog.getCatalogName());
//                if(!file.exists() || !file.isDirectory())
//                    continue;
//
//                File[] files = file.listFiles();
//                for (File f : files) {
//                    if(f.isDirectory()){
//                        continue;
//                    }
//                    Pair<RawItem,RawFile> p = parseRawFiles(f);
//
//                    if(p==null)  continue;
////                    设置RAWItem
//                    RawItemMapper rawItemMapper = session.getMapper(RawItemMapper.class);
//                    p.first().setRawInternalId(rawItemMapper.maxInternalId().add(BigDecimal.ONE));
//                    StringBuilder rawUrl=new StringBuilder();
//                    rawUrl.append("file:");
//                    rawUrl.append(Configuration.getManagerConfig().getLocalRawDataRoot());
//                    rawUrl.append(File.separator);
//                    rawUrl.append(f.getName().replace("raw","zip").trim());
//                    p.first().setRawUrl(rawUrl.toString());
//                    p.first().setRawCatalog(rawCatalog.getCatalogInternalId());
//                    rawItemMapper.insert(p.first());
//                    RawCatalogMapper rawCatalogMapper = session.getMapper(RawCatalogMapper.class);
//                    rawCatalogMapper.insert(rawCatalog);
//                    session.commit();
//
//                    writeToFileSystem(p.first(),p.second());
//                }
//            }
//
//        }
//        catch (Exception e){
//            e.printStackTrace();
//        }
        return true;
    }

    @Override
    public boolean delete(RawItem rawItem) {
        return false;
    }

    @Override
    public boolean delete(RawAll rawAll) {
        return false;
    }

    @Override
    public boolean update(RawItem rawItem, RawFile rawFile) {
        try{
            RawItemMapper rawItemMapper = session.getMapper(RawItemMapper.class);
            rawItemMapper.updateByPrimaryKey(rawItem);

            RawFileMapper rawFileMapper= session.getMapper(RawFileMapper.class);
            rawFileMapper.updateByPrimaryKey(rawFile);

            session.commit();
            return true;

        }
        catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public boolean update(RawAll rawAll) {
        RawAllMapper rawAllMapper = session.getMapper(RawAllMapper.class);
        rawAllMapper.updateByPrimaryKey(rawAll);

        Pair<RawItem,RawFile> p = RawUtils.fromRawAll(rawAll);
        return update(p.first(),p.second());
    }

    @Override
    public RawAll queryByInternalId(BigDecimal rawInternalId) {
        try{
            RawItemMapper rawItemMapper = session.getMapper(RawItemMapper.class);
            RawItem rawItem = rawItemMapper.selectByPrimaryKey(rawInternalId);

//            Pair<String,String> p = parseRawUrl(rawItem.getRawUrl());
//            RawFile rawFile = readFromFileSystem(p.first(),p.second());
            RawFileMapper rawFileMapper= session.getMapper(RawFileMapper.class);
            RawFile rawFile = rawFileMapper.selectByPrimaryKey(rawInternalId);
            rawFile.setRawInternalId(rawInternalId);

            RawAll rawAll = RawUtils.toRawAll(rawItem,rawFile);
            return rawAll;
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<RawItem> queryItemByInternalId(BigDecimal rawInternalId) {

        List<RawItem> res = new ArrayList<>();
        try{
            RawItemMapper rawItemMapper = session.getMapper(RawItemMapper.class);
            RawItem rawItem = rawItemMapper.selectByPrimaryKey(rawInternalId);

            res.add(rawItem);
            return res;
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public List<RawAll> queryByEnTitle(String rawEnTitle) {
        return null;
    }

    @Override
    public List<RawAll> queryByComment(String rawCnTitle) {
        return null;
    }

    @Override
    public List<RawAll> queryByType(String rawType) {
        return null;
    }

    @Override
    public List<RawAll> queryByAppendDate(TimeValue begin, TimeValue end) {
        return null;
    }

    @Override
    public List<RawAll> query(Map<String, Object> parameters) {
        return null;
    }
}
